package com.miku.sys.utils;

import java.util.Date;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.miku.common.Servlets;
import com.miku.db.sys.entity.SysRole;
import com.miku.db.sys.entity.SysUser;
import com.miku.sys.dao.SysRoleDaoI;
import com.miku.sys.dao.SysUserDaoI;
import com.miku.sys.security.realm.SystemAuthorizingRealm.Principal;
import com.miku.sys.security.utils.Digests;
import com.miku.utils.Encodes;
import com.miku.utils.SpringContextHolder;
import com.miku.utils.StringUtils;

/**
 * 用户工具类
 */
public class UserUtils {
	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;
	
	private static SysUserDaoI userDao = SpringContextHolder.getBean(SysUserDaoI.class);
	private static SysRoleDaoI roleDao = SpringContextHolder.getBean(SysRoleDaoI.class);

	/**
	 * 根据ID获取用户
	 * @param id
	 * @return 取不到返回null
	 */
	public static SysUser get(int id){
		return userDao.findByID(id);
	}
	
	/**
	 * 获取当前用户
	 * @return 取不到返回 new User()
	 */
	public static SysUser getUser(){
		Principal principal = getPrincipal();
		if (principal!=null){
			SysUser user = get(principal.getId());
			if (user != null){
				return user;
			}
			return null;
		}
		// 如果没有登录，则返回实例化空的User对象。
		return null;
	}
	
	/**
	 * 直接获取当前用户的id
	 * @return
	 */
	public static int getCurrentUserID(){
		Principal p = getPrincipal();
		if(p == null) return 0;
		return p.getId();
	}

	/**
	 * 获取当前用户角色列表
	 * @return
	 */
	public static List<SysRole> getRoleList(){
		SysUser user = getUser();
		return user != null ? user.getRoles() : null;
	}
	
	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}
	
	//获取当前用户的昵称
	public static String getCurrentUserNickName(){
		Principal p = getPrincipal();
		if(p != null){
			return p.getNickName();
		}
		return null;
	}
	
	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal)subject.getPrincipal();
			if (principal != null){ // && subject.isAuthenticated()
				return principal;
			}
//			subject.logout();
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	public static Session getSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
//			subject.logout();
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	/**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
	}
	
	public static String entryptPasswordBySalt(String plainPassword, byte[] salt) {
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
	}
	
	/**
	 * 校验密码是否一致
	 * @param encodePassword   编码后的hash密码   fab1223ca2de   这种十六进制已经编码后的东西
	 * @param rawPassword		  原始密码串              123                   明文原始密码
	 * @return
	 */
	public static boolean equalsPassword(String encodePassword, String rawPassword){
		byte[] salt = Encodes.decodeHex(encodePassword.substring(0,16));
		return encodePassword.equals(entryptPasswordBySalt(rawPassword, salt));
	}
	
	// ============== User Cache ==============
	
	public static Object getCache(String key) {
		return getCache(key, null);
	}
	
	public static Object getCache(String key, Object defaultValue) {
//		Object obj = getCacheMap().get(key);
		Object obj = getSession().getAttribute(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
//		getCacheMap().put(key, value);
		getSession().setAttribute(key, value);
	}

	public static void removeCache(String key) {
//		getCacheMap().remove(key);
		getSession().removeAttribute(key);
	}
	
	public static void updatePassword(SysUser user, String newPassword) {
		user.setPassword(UserUtils.entryptPassword(newPassword));
		userDao.update(user);
	}
	
//	public static Map<String, Object> getCacheMap(){
//		Principal principal = getPrincipal();
//		if(principal!=null){
//			return principal.getCacheMap();
//		}
//		return new HashMap<String, Object>();
//	}
	
	//更新用户最后的登录信息
	public static void updateUserLoginInfo(SysUser user) {
		user.setPrevlogin(user.getLastlogin());
		user.setPrevloginIP(user.getLastloginIP());
		user.setLastloginIP(StringUtils.getRemoteAddr(Servlets.getRequest()));
		user.setLastlogin(new Date());
	}
}
